package com.naton.mydemo.model.dao;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.naton.mydemo.bean.ChatMessage;
import com.naton.mydemo.bean.User;
import com.naton.mydemo.ui.MyApplication;

import org.jetbrains.annotations.NotNull;

import java.util.Objects;

/**
 * 1. 必须是abstract类 并且继承 RoomDatabase
 * 2. 必须在类头的注解中包含于数据库关联的实体列表（Entity对应的类）
 */
@Database(entities = { User.class , ChatMessage.class}, version = 1,exportSchema = false)
public abstract class AppDataBase extends RoomDatabase {


    private static String DATA_BASE_NAME = "appDB.db";

    /**
     * 3. 包含具有0个参数的抽象方法  并返回用 @Dao注解的类
     * @return
     */
    public abstract UserDao userDao();
    public abstract ChatMessageDao chatMessageDao();

    private static volatile AppDataBase INSTANCE;


    /**
     * 关于 AppDataBase的使用
     * 1. 如果database的版本号不变  app操作数据库的时候会直接crash掉（错误的做法）
     * 2. 如果增加database版本号 但是不提供Migration ， App 操作数据库表的时候会直接crash掉（错误的做法）
     * 3. 如果增加database的版本号 同时开启 fallbackToDestructiveMigration 这个时候之前的数据会被清空掉
     *
     * 如下 fallbackToDestructiveMigration() 设置 （不推荐）
     * @return
     */
    public static AppDataBase getDataBase(){

        if (INSTANCE == null){
            synchronized (AppDataBase.class){
                if (INSTANCE == null){
                    /**
                     * Database 有两种生成方式
                     * 1. Room.databaseBuilder(): 生成Database对象  并且创建一个存在文件系统中的数据库
                     * 2. Room.inMemoryDatabaseBuilder(): 生成Database对象并且创建一个存在内存中的数据库，
                     *    当应用退出的时候（应用进程关闭）数据库也消失
                     */
                    INSTANCE = Room.databaseBuilder(Objects.requireNonNull(MyApplication.getInstance()).getApplicationContext()
                            , AppDataBase.class , DATA_BASE_NAME)
                            //设置时候允许在主线程做查询操作
                            .allowMainThreadQueries()
                            //设置数据库升级（迁移）逻辑
//                            .addMigrations(MIGRATION_1_2)
//                            .setJournalMode() //设置数据库的日志格式
                            //设置迁移数据库如果发生错误 将会重新创建数据库 而不是发生崩溃
                            .fallbackToDestructiveMigration()
                            //设置从某个版本开始迁移数据库如果发生错误 将会重建数据库  而不是发生崩溃
//                            .fallbackToDestructiveMigrationFrom(int... startVersions)
                            .addCallback(new Callback() {
                                @Override
                                public void onCreate(@NonNull @NotNull SupportSQLiteDatabase db) {
                                    super.onCreate(db);
                                }

                                @Override
                                public void onOpen(@NonNull @NotNull SupportSQLiteDatabase db) {
                                    super.onOpen(db);
                                }
                            })
                            .build();
                }
            }
        }

        return INSTANCE;
    }


    private static final Migration MIGRATION_1_2 = new Migration(1 , 2) {
        @Override
        public void migrate(@NonNull @NotNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE User ADD COLUMN tel String");
        }
    };
}
